﻿/*
 * Copyright(C) 2012,ajayumi 保留所有权利。( All rights reserved. )
 * 
 * 文件名称：SymmetricCryptoProvider.cs
 * 摘    要：
 * 当前版本：1.0
 * 作    者：黄乙冬 (ajayumi)
 * 创建日期：2012年6月10日星期日
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace ajayumi.Platform.Core.Security
{
    /// <summary>
    /// 对称加密算法提供者的基类
    /// </summary>
    public abstract class SymmetricCryptoProvider : CryptoProvider
    {
        #region Properties

        /// <summary>
        /// 加密对象
        /// </summary>
        public SymmetricAlgorithm SymAlg { get; protected set; }

        /// <summary>
        /// 密钥
        /// </summary>
        public string CryptoKey { get; protected set; }

        #endregion


        protected SymmetricCryptoProvider(string name)
            : base(name)
        {
        }

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);
            config.Add("key", SecurityConfig.CryptoKey);

            this.CryptoKey = config.GetValues("key")[0];
        }

        public override string Encrypt(string plainStr)
        {
            if (string.IsNullOrEmpty(plainStr))
            {
                return plainStr;
            }
            return EncryptString(plainStr);

        }

        public override string Decrypt(string encryptedStr)
        {
            if (string.IsNullOrEmpty(encryptedStr))
            {
                return encryptedStr;
            }

            return DecryptString(encryptedStr);
        }

        // Encrypts a configuration section and returns 
        // the encrypted XML as a string.
        protected string EncryptString(string encryptValue)
        {
            byte[] valBytes = Encoding.Unicode.GetBytes(encryptValue);

            if (this.SymAlg == null)
            { throw new NotImplementedException(); }

            ICryptoTransform transform = SymAlg.CreateEncryptor();

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms,
                transform, CryptoStreamMode.Write);
            cs.Write(valBytes, 0, valBytes.Length);
            cs.FlushFinalBlock();
            byte[] returnBytes = ms.ToArray();
            cs.Close();

            return Convert.ToBase64String(returnBytes);
        }


        // Decrypts an encrypted configuration section and 
        // returns the unencrypted XML as a string.
        protected string DecryptString(string encryptedValue)
        {
            byte[] valBytes = Convert.FromBase64String(encryptedValue);

            if (this.SymAlg == null)
            { throw new NotImplementedException(); }

            ICryptoTransform transform = SymAlg.CreateDecryptor();

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms,
                transform, CryptoStreamMode.Write);
            cs.Write(valBytes, 0, valBytes.Length);
            cs.FlushFinalBlock();
            byte[] returnBytes = ms.ToArray();
            cs.Close();

            return Encoding.Unicode.GetString(returnBytes);
        }

        public override void Dispose()
        {
            this.SymAlg.Dispose();
        }
    }
}
